package org.akomantoso.core.io.util;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.akomantoso.core.data.ParliamentaryAnalysisElement;
import org.akomantoso.core.data.QuorumVerification;
import org.akomantoso.core.data.Recount;
import org.akomantoso.core.data.Voting;
import org.akomantoso.core.io.Input;
import org.akomantoso.core.io.InputConstants;

/**
 * @author <a href="mailto:jacques.militello@gmail.com">Jacques Militello</a>
 */
public final class ParliamentaryAnalysisElementUtil {

	private ParliamentaryAnalysisElementUtil() {
	}

	public static final Map<String, Instantiator<ParliamentaryAnalysisElement>> MAP;

	private static ParliamentaryAnalysisElement instantiate(String elementName) {

		final Instantiator<ParliamentaryAnalysisElement> instatiator = MAP.get(elementName);
		if (instatiator == null) {
			throw new RuntimeException("Tag [" + elementName + "] not supported ParliamentaryAnalysisElement ?!?");
		}
		return instatiator.instantiate();

	}

	public static void read(Input in, List<ParliamentaryAnalysisElement> elements)
			throws IOException {

		final String localName = in.getLocalName();
		in.readNextStartElement();
		
		ParliamentaryAnalysisElement element = null;

		while (true) {

			switch (in.getEventType()) {
			case InputConstants.START_ELEMENT:
				elements.add(element = instantiate(in.getLocalName()));
				element.readExternal(in);
				break;
			case InputConstants.END_ELEMENT:
				if (localName.equals(in.getLocalName())) {
					return;
				}
			}

			in.readNext();
		}
	}

	static {
		Map<String, Instantiator<ParliamentaryAnalysisElement>> temp = new HashMap<String, Instantiator<ParliamentaryAnalysisElement>>();

		// voting
		temp.put(Voting.ELEMENT, new Instantiator<ParliamentaryAnalysisElement>() {
			public Voting instantiate() {
				return new Voting();
			}
		});

		// recount
		temp.put(Recount.ELEMENT, new Instantiator<ParliamentaryAnalysisElement>() {
			public Recount instantiate() {
				return new Recount();
			}
		});
		
		// quorumVerificaiton
		temp.put(QuorumVerification.ELEMENT, new Instantiator<ParliamentaryAnalysisElement>() {
			public QuorumVerification instantiate() {
				return new QuorumVerification();
			}
		});

		MAP = Collections.unmodifiableMap(temp);
	}
}
